/******************************************
 * Nombre del archivo: Mapcar.java
 * Universidad del Valle de Guatemala
 * Curso: Algoritmos y Estructura de Datos
 * Autores:
 *      * Martín Guzmán     08041
 *      * David Hsieh       08225
 *      * Eduardo Mejicano  08058
 *      * Kevin Sánchez     08302
 * Fecha: 19 de septiembre de 2009
 * Descripción:
*******************************************/
import java.util.LinkedList;
import java.util.ArrayList;

/**
 *
 * @author martin
 */
public class Mapcar {
    String result;

    
    public Mapcar(String mapcar_funtion)
    {
        //System.out.println("New mapcar ."+mapcar_funtion+".");
        ArrayList<String> tempo = Arreglar_texto(mapcar_funtion);
        
        //System.out.println("length"+tempo.size());
        /*
        for(int i=0;i<tempo.size();i++){
            System.out.println("."+tempo.get(i)+".");
        }
        */
        if(Revisar(tempo)==true){
            System.out.println("blabla: "+tempo);
            At_Lista_Literal lista_lit = new At_Lista_Literal(tempo.get(2),true);
            //System.out.println("blabla");
            ///*
            for(int i=0;i<lista_lit.getList().size();i++){
                System.out.println("."+lista_lit.getList().get(i)+".");
            }
            //*/
            LinkedList<String> respuesta = new LinkedList<String>();

            for(int i=0;i<lista_lit.getList().size();i++){

                    int indice=Funcion.Buscar_Indice(tempo.get(1).substring(1,tempo.get(1).length()));
                    //String temporal2=Funcion.getFunciones().get(indice).replace(new At_Lista_Literal(texto2.substring(0,texto2.length()-1)));
                    String temporal2=Funcion.getFunciones().get(indice).replace(lista_lit.getList().get(i));
                    if(temporal2.compareToIgnoreCase("")!=0){
                        try{
                            respuesta.add(Funcion.getFunciones().get(indice).Obtener_valor(temporal2));
                        }
                        catch(Exception exp){
                            respuesta.clear();
                            System.out.println("Operands do not match in the funtion "+(tempo.get(1).substring(1,tempo.get(1).length()-1)));
                            break;
                        }
                    }
                    else{
                        respuesta.clear();
                        System.out.println("No se encuentra entre las funciones");
                        break;
                    }
            }
            result="";
            if(respuesta.size()!=0)
            {
                String result2="(";
                for(int i=0;i<respuesta.size();i++){
                    result2+=respuesta.get(i)+" ";
                }
                result=result2.substring(0,result2.length()-1)+")";
                //System.out.println("resultado de mapcar ."+result+".");
            }
        }
        else
            result = "";

    }

    public String getResult(){
        return result;
    }

    /*****************************************
     * Método: Revisar
     * Autor: Martín Guzmán
     * Uso: Revisa la sintaxis de mapcar
     * Retorno: booleano true si es correcta la
     *      sintaxis
     *****************************************/
    public boolean Revisar(ArrayList<String> lista){

        if (lista.get(0).compareToIgnoreCase("MAPCAR")!=0){
            return false;
        }
        //System.out.println(lista.get(1)+".");
        if (Funcion.Buscar(lista.get(1).substring(1,lista.get(1).length()))==false){
            //significaría que no está entre la lista de funciones
            return false;
        }
        //System.out.println(lista.get(1)+".");
        if(lista.get(1).startsWith("'")==false){
            //significaría que no hay ' antes del nombre de la función
            return false;
        }
        //System.out.println(lista.get(1)+".");
        if(lista.get(2).compareTo("'")==0){
            lista.remove(2);
            String temp = lista.get(2);
            lista.remove(2);
            lista.add(2,"',"+temp);
        }


        return true;
    }

    /*****************************************
     * Método: Arreglar_texto
     * Autor: Martín Guzmán
     * Uso: divide en átomos el texto
     * Retorno: guarda los átomos en una lista.
     *****************************************/
    public ArrayList<String> Arreglar_texto(String texto_lista){
        texto_lista=texto_lista.replaceAll("MAPCAR'","MAPCAR,'");
        texto_lista=texto_lista.replaceAll(",MAPCAR","MAPCAR");

        String[] temporal=texto_lista.split(",");
        
        //pasar a una lista el arreglo de strings
        ArrayList<String> temporal_lista = new ArrayList<String>();
        for(int i=0;i<temporal.length;i++)
        {
            temporal_lista.add(temporal[i]);
        }
        //***********************************
        ArrayList<String> temporal_a_agregar = new ArrayList<String>();
        for(int i=0;i<temporal_lista.size();i++)
        {
            String sub_cadena=temporal_lista.get(i);
            if (temporal_lista.get(i).startsWith("("))//agrupar hasta que se cierre este paréntesis
            {
                int parentesis=1;
                int posicion=i;
                for(int j=i+1;j<temporal_lista.size();j++){
                    if(temporal[j].contains(")"))
                        parentesis--;
                    if (parentesis==0){
                        posicion=j;
                        break;
                    }
                    if(temporal[j].startsWith("("))
                        parentesis++;

                }
                sub_cadena="";
                //System.out.println("i"+i+" j:"+posicion);//TODO quitar esto
                for(int a=i;a<=posicion;a++){
                   sub_cadena+=","+temporal_lista.get(a);
                }
                sub_cadena=sub_cadena.substring(1, sub_cadena.length());//para quitarle la última ","
                i=posicion;
            }
            //System.out.println("Sub-cadena: ."+sub_cadena+".");//TODO quitar esto
            temporal_a_agregar.add(sub_cadena);
        }
        
        return temporal_a_agregar;
    }

}
